<script setup lang="ts">
import { DeviceDTO } from '@/api/entity/device'
import { Download, Plus, Search } from '@element-plus/icons-vue'
import { ElForm, ElTable, ElTree } from 'element-plus'
import { ElTreeData } from '@typings/element-plus'
import { getDeviceListByAdminRoleAPI } from '@/api/device'
import { PreferenceDB } from '@utils/indexedDB/preference'
import { EmptyEnum, EmptyState } from '@yk/components/empty-box/type'
import YkEmptyBox from '@yk/components/empty-box/YkEmptyBox.vue'
import { TableUtil } from '@utils/table-util'
import { useAppStore } from '@/pinia'
import { Pages } from '@typings/pages'
import { DeviceRoleDTO } from '@/api/entity/share'
import {
  bulkShareDeviceAPI,
  delShareInfoAPI,
  deviceShareByPhoneAPI,
  deviceShareByQRCodeAPI,
  editShareInfoAPI,
  getDeviceShareListByPageAPI
} from '@/api/share'
import YkTableColumn from '@yk/components/table-column/YkTableColumn.vue'
import YkPagination from '@yk/components/pagination/YkPagination.vue'
import YkDatePicker from '@yk/components/date-picker/YkDatePicker.vue'
import { DeviceRoleUtil } from '@/dataset/device-role'
import { MountedCheck } from '@/utils'
import { ObjectUtil } from '@utils/object-util'
import { ElValidator, phoneRule, required } from '@utils/form-rule'
import { LoadingSvg } from '@assets/styles/loading'

defineOptions({ name: 'ShareDeviceList' })
const appStore = useAppStore()

const mc = new MountedCheck()
onMounted(() => {
  DeviceRoleUtil.updateRole()
  getDeviceTreeList()
  mc.end()
})

onActivated(() => {
  if (mc.isMounted()) return
  DeviceRoleUtil.updateRole()
  tableDataRef.value.doLayout()
})

// region TODO 查询
const searchParams = reactive({
  // 权限类型 0-仅查看、1-允许控制、3-可管理
  roleType: '',
  // 共享状态（0-共享中、1-已失效）
  status: '',
  // 开始时间
  startTime: '',
  // 结束时间
  endTime: ''
})
function searchHandle () {
  pages.pageNum = 1
  getTableData()
}
// endregion

// region TODO 表格数据
const pages = reactive(new Pages())
const tableData = shallowRef<DeviceRoleDTO[]>([])
const tableDataRef = shallowRef<InstanceType<typeof ElTable>>()
function getTableData () {
  const loading = ElLoading.service()
  getDeviceShareListByPageAPI({
    ...pages.getParams(),
    param: {
      ...searchParams,
      deviceId: currentDevice.value.id
    }
  }).then((res) => {
    res.result().then((rdata) => {
      tableData.value = rdata.records
      pages.total = rdata.total
    })
  })
  loading.close()
}
function delTableItem (id: string) {
  ElMessageBox.confirm('删除当前记录？', '删除提醒').then(() => {
    const loading = ElLoading.service()
    delShareInfoAPI({ id }).then(res => {
      res.result().then(() => {
        ElMessage.success('删除成功')
        getTableData()
      })
    }).finally(loading.close)
  })
}
// endregion

// region TODO 取消分享
function unshare (id: string) {
  ElMessageBox.confirm('取消后对方将无法查看该设备，是否确定？', '取消分享').then(() => {
    const loading = ElLoading.service()
    editShareInfoAPI({ id, status: '1' }).then(res => {
      res.result().then(() => {
        ElMessage.success('已取消')
        getTableData()
      })
    }).finally(loading.close)
  })
}
// endregion

// region TODO 分享表单
class ShareSaveForm {
  id = null
  // 共享有效期
  expiredTime = ''
  // 权限类型 0-仅查看、1-允许控制、3-可管理
  roleType = '0'
  // 账户手机号
  phone = ''
  // 共享方式 0-手机号，1-二维码
  type = '0'
  // 二维码有效时间
  timeOutSeconds = 300
}
const shareSaveForm = ref(new ShareSaveForm())
const shareSaveFormRef = ref<InstanceType<typeof ElForm>>()

// 校验设备的分享时间是否超出权限范围
function expiredTimeValidator (deviceId: string) {
  const role = DeviceRoleUtil.getRole(deviceId)
  if (role.roleType === '3') {
    const r1 = role.expiredTime ? new Date(role.expiredTime).getTime() : Infinity
    const r2 = shareSaveForm.value.expiredTime ? new Date(shareSaveForm.value.expiredTime).getTime() : Infinity
    if (r2 > r1) {
      return { result: false, expiredTime: role.expiredTime }
    }
  }
  return { result: true }
}
const shareSaveFormRules = ref({
  expiredTime: [{
    validator (rule: any, value: any, callback: (error?: Error) => void) {
      if (isBulkSharing.value) {
        const nodes = deviceTreeRef.value.getCheckedNodes()
        let minShare = { expiredTime: Infinity, deviceName: '', deviceId: '' }
        for (let i = 0; i < nodes.length; i++) {
          const device = nodes[i]
          const role = DeviceRoleUtil.getRole(device.id)
          const _expiredTime = new Date(role.expiredTime).getTime()
          if (role.roleType === '3' && role.expiredTime && _expiredTime < minShare.expiredTime) {
            minShare = {
              deviceId: device.id,
              expiredTime: _expiredTime,
              deviceName: device.deviceName
            }
          }
        }
        if (minShare.deviceId) {
          const result = expiredTimeValidator(minShare.deviceId)
          callback(result.result ? undefined : Error(`设备【${minShare.deviceName}】的分享时间是${result.expiredTime}，你的分享时间不能大于该时间`))
        } else {
          callback(undefined)
        }
      } else {
        const result = expiredTimeValidator(currentDevice.value.id)
        callback(result.result ? undefined : Error('你的分享时间不能超过' + result.expiredTime))
      }
    },
    trigger: 'blur'
  } as ElValidator],
  roleType: [required('共享权限为必填项')],
  type: [required('共享方式为必填项')],
  phone: [required('手机号为必填项'), phoneRule]
})
const QRCodeUrl = shallowRef('')

// 提交共享
function shareSaveSubmitHandle () {
  shareSaveFormRef.value.validate().then(() => {
    // 如果是编辑
    if (shareSaveForm.value.id) {
      shareEditSubmitHandle()
    } else if (isBulkSharing.value) { // 如果是批量分享
      submitBulkShareDevice()
    } else {
      // 如果是分享
      if (shareSaveForm.value.type === '0') {
        deviceShareByPhone()
      } else {
        deviceShareByQRCode()
      }
    }
  })
}

// 编辑提交
function shareEditSubmitHandle () {
  const loading = ElLoading.service()
  editShareInfoAPI({
    deviceId: currentDevice.value.id,
    ...shareSaveForm.value
  }).then((res) => {
    res.result().then(() => {
      ElMessage.success('保存成功')
      getTableData()
      shareSaveDialogModel.value = false
    })
  }).finally(loading.close)
}

// 手机号共享
function deviceShareByPhone () {
  const loading = ElLoading.service()
  deviceShareByPhoneAPI({
    deviceId: currentDevice.value.id,
    ...shareSaveForm.value
  }).then((res) => {
    res.result().then(() => {
      ElMessage.success('设备分享成功')
      closeShareSaveDialog()
      getTableData()
    })
  }).finally(loading.close)
}
// 二维码共享
function deviceShareByQRCode () {
  deviceShareByQRCodeAPI({
    deviceId: currentDevice.value.id,
    ...shareSaveForm.value
  }).then((res) => {
    if (res.data instanceof Blob) {
      QRCodeUrl.value && URL.revokeObjectURL(QRCodeUrl.value)
      QRCodeUrl.value = URL.createObjectURL(res.data)
    }
  })
}

onBeforeUnmount(() => {
  QRCodeUrl.value && URL.revokeObjectURL(QRCodeUrl.value)
})

// endregion

// region TODO 分享表单对话框
const shareSaveDialogModel = ref(false)
function showShareSaveDialog (item?: DeviceRoleDTO) {
  shareSaveDialogModel.value = true
  shareSaveForm.value = new ShareSaveForm()
  if (item) {
    nextTick(() => {
      ObjectUtil.updateVal(shareSaveForm.value, item)
    })
  }
}
function closeShareSaveDialog () {
  shareSaveFormRef.value.resetFields()
  shareSaveForm.value.id = null
  shareSaveDialogModel.value = false
  isBulkSharing.value = false
}
// endregion

// region TODO 批量分享
const isBulkSharing = shallowRef(false)
function bulkSharing () {
  const ids = deviceTreeRef.value.getCheckedKeys()
  if (!ids.length) {
    ElMessage.info('请勾选要分享的设备')
    return
  }
  isBulkSharing.value = true
  showShareSaveDialog()
}
function submitBulkShareDevice () {
  const ids = deviceTreeRef.value.getCheckedKeys()
  if (!ids.length) {
    ElMessage.info('请勾选要分享的设备')
    return
  }
  const loading = ElLoading.service()
  bulkShareDeviceAPI({
    ...shareSaveForm.value,
    deviceIdList: deviceTreeRef.value.getCheckedKeys() as string[]
  }).then((res) => {
    res.result().then(() => {
      ElMessage.success('分享成功')
      getTableData()
      closeShareSaveDialog()
    })
  }).finally(loading.close)
}
// endregion

// region TODO 设备树
const currentDevice = shallowRef<DeviceDTO>(null)
const deviceTreeRef = shallowRef<InstanceType<typeof ElTree>>()
type DeviceTreeNodeType = ElTreeData<DeviceDTO>
const deviceTreeList = ref<DeviceTreeNodeType[]>([])

// 获取设备列表
function getDeviceTreeList () {
  const loading = ElLoading.service()
  getDeviceListByAdminRoleAPI().then((res) => {
    res.result().then((rdata) => {
      const data = rdata.data
      deviceTreeList.value = data.map<DeviceTreeNodeType>(item => {
        return {
          key: item.id,
          value: item.id,
          label: item.deviceName,
          ...item
        }
      })
      // 如果树搜索有搜索条件，执行一次搜索
      if (treeFilterText.value) {
        nextTick(() => {
          deviceTreeRef.value.filter(treeFilterText.value)
        })
      }
      // 根据最后一次操作的设备选中设备
      PreferenceDB.DeviceShare.getItem('currentDevice').then((e) => {
        if (e) setCurrentDeviceById(e)
        else if (data[0])setCurrentDeviceById(data[0].id)
      })
    })
  }).finally(loading.close)
}

// 树节点点击实现
function deviceTreeNodeClickHandle (data: DeviceTreeNodeType) {
  setCurrentDevice(data)
}
// 设置当前选中设备
function setCurrentDevice (data: DeviceDTO) {
  if (data.id !== currentDevice.value?.id) {
    currentDevice.value = data
    searchHandle()
    PreferenceDB.DeviceShare.setItem('currentDevice', data.id)
    // getDeviceDetailByIdAPI({ id: data.id }).then((res) => {
    //   res.result().then((rdata) => {
    //     currentDevice.value = rdata.data
    //     PreferenceDB.DeviceData.setItem('currentDevice', data.id)
    //   })
    // })
  }
}
function setCurrentDeviceById (id: string) {
  const node = deviceTreeRef.value.getNode(id)
  // 如果树中还有这个设备
  if (node) {
    // 选中这个设备
    setCurrentDevice(node.data)
    // deviceDataState.value = EmptyEnum.SUCCESS
  }
}

// region TODO 树搜索
const treeFilterText = ref('')
watch(treeFilterText, (val) => {
  deviceTreeRef.value.filter(val)
})
const filterNode = (value: string, data: DeviceTreeNodeType) => {
  if (!value) return true
  return data.label.includes(value)
}
// endregion
// endregion

// region TODO 页面无变量提醒
const deviceDataState = shallowRef<EmptyState>(EmptyEnum.NONE)
watch(currentDevice, () => {
  if (currentDevice.value) {
    deviceDataState.value = EmptyEnum.SUCCESS
  } else {
    deviceDataState.value = { type: EmptyEnum.EMPTY_VAR, description: '暂无数据，请选择设备' }
  }
}, { immediate: true })

// endregion
</script>

<template>
  <div class="layout_view is-loading-mask d-flex h-100" style="min-height: 400px">
    <!--设备列表-->
    <div class="d-flex position-relative h-100" style="flex-shrink: 0;">
      <div class="c_card-white h-100" style="width: 320px;">
        <div class="c_card_header bor-divider-b">
          <div class="c_card-title">设备列表</div>
          <div class="c_header_right">
            <el-link type="primary" @click="bulkSharing">
              <el-icon><Plus /></el-icon>
              <span>批量分享</span>
            </el-link>
          </div>
        </div>
        <div class="pt-16" style="height: var(--card-body-height);">
          <div class="d-flex-between-center">
            <el-input v-model="treeFilterText" class="c_input-search" placeholder="输入名称搜索" :prefix-icon="Search as any" />
            <refresh-btn class="fs-24 color-primary ml-2" @click="getDeviceTreeList()" />
          </div>
          <div class="overflow-auto mt-16 device-tree" style="height: calc(100% - 50px);">
            <el-tree
              ref="deviceTreeRef" class="" :data="deviceTreeList"
              show-checkbox
              node-key="key" :filter-node-method="filterNode as any"
              @node-click="deviceTreeNodeClickHandle"
            >
              <template #default="{ data }">
                <div :class="{ 'is-active': currentDevice?.id === data.value }">{{ data.label }}</div>
              </template>
            </el-tree>
          </div>
        </div>
      </div>
    </div>
    <!--右侧内容-->
    <div v-loading="isBulkSharing" :element-loading-svg="LoadingSvg" class="flex-1 is-loading-mask w-0 ml-12 c_card-page">
      <div class="c_card_header c_card-title bor-divider-b">设备分享列表</div>
      <yk-empty-box :state="deviceDataState" :image-size="192" class="" :class="[!currentDevice && 'h-80']">
        <!--搜索表单-->
        <el-form inline class="c_form-search mt-3" @submit.prevent="searchHandle">
          <el-form-item>
            <el-select v-model="searchParams.roleType" placeholder="全部权限" clearable>
              <el-option value="">全部</el-option>
              <el-option label="仅查看" value="0" />
              <el-option label="允许控制" value="1" />
              <el-option label="可管理" value="3" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-select v-model="searchParams.status" placeholder="全部状态" clearable>
              <el-option value="">全部</el-option>
              <el-option label="共享中" value="0" />
              <el-option label="已失效" value="1" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <yk-date-picker v-model:start="searchParams.startTime" v-model:end="searchParams.endTime" type="datetimerange" clearable />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="searchHandle">查询</el-button>
          </el-form-item>
          <el-form-item class="float-right mr-0">
            <el-button type="primary" :icon="Plus as any" @click="showShareSaveDialog()">添加分享</el-button>
          </el-form-item>
        </el-form>
        <!--表格-->
        <el-table
          ref="tableDataRef" class="c_table-page w-100" stripe
          :data="tableData"
          max-height="calc(var(--ref-height) - 190px)"
        >
          <el-table-column label="#" type="index" :index="TableUtil.indexMethod.bind(null, pages)" />
          <yk-table-column label="共享账号" prop="phone" />
          <!--<yk-table-column label="公司名称" prop="corporationName" />-->
          <yk-table-column label="权限类型" prop="roleType">
            <template #default="scope">
              {{ { 0: '仅查看', 1: '允许控制', 3: '可管理' }[scope.row.roleType] }}
            </template>
          </yk-table-column>
          <el-table-column label="共享有效期">
            <template #default="scope">{{ scope.row.expiredTime || '永久' }}</template>
          </el-table-column>
          <yk-table-column label="共享时间" prop="createdAt" sortable />
          <el-table-column label="共享状态" prop="status" sortable>
            <template #default="scope">
              <el-tag v-if="scope.row.status === '1'" type="danger" effect="light" size="small">已失效</el-tag>
              <el-tag v-else-if="scope.row.status === '0'" effect="light" size="small">共享中</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150px">
            <template #default="scope">
              <div class="c_table-operation">
                <template v-if="scope.row.status === '0'">
                  <template v-if="appStore.userInfo.id !== scope.row.userId">
                    <el-link type="primary" size="small" @click="showShareSaveDialog(scope.row)">修改</el-link>
                    <el-link type="danger" size="small" @click="unshare(scope.row.id)">取消共享</el-link>
                  </template>
                  <span v-else>不可操作</span>
                </template>
                <el-link v-if="scope.row.status === '1'" type="danger" size="small" @click="delTableItem(scope.row.id)">删除记录</el-link>
              </div>
            </template>
          </el-table-column>
        </el-table>
        <!--分页-->
        <el-affix target=".c_table-page" position="bottom" :offset="0">
          <yk-pagination class="c_table-pagination-page px-3" :pages="pages" @handle="getTableData" />
        </el-affix>
      </yk-empty-box>
    </div>
    <!--分享表单-->
    <el-dialog
      v-model="shareSaveDialogModel" :close-on-click-modal="false" draggable
      :modal="shareSaveDialogModel && !isBulkSharing" :title="shareSaveForm.id ? '修改共享' : isBulkSharing ? '批量共享' : '共享设备'"
      width="500px" @close="closeShareSaveDialog"
    >
      <el-form
        ref="shareSaveFormRef" :model="shareSaveForm" :rules="shareSaveFormRules"
        class="mt-16 c_form-save"
        label-width="140px"
      >
        <el-form-item label="共享权限类型：">
          <el-radio-group v-model="shareSaveForm.roleType">
            <el-radio label="0">仅查看</el-radio>
            <el-radio label="1">允许控制</el-radio>
            <el-radio label="3">可管理</el-radio>
          </el-radio-group>
          <p v-if="shareSaveForm.id" class="c_form-tip" style="line-height: 20px;">修改权限类型后30秒或重新进入小程序后生效，<br>网页端刷新页面生效</p>
        </el-form-item>

        <el-form-item label="共享有效期：" prop="expiredTime" class="w-100 mt-3">
          <yk-date-picker
            v-model="shareSaveForm.expiredTime" class="w-100" type="datetime"
            optional-scope="after" clearable
            placeholder="选择共享有效期"
          />
        </el-form-item>
        <template v-if="!shareSaveForm.id">
          <el-form-item v-if="shareSaveForm.type === '0'" label="手机号" prop="phone">
            <el-input v-model="shareSaveForm.phone" />
          </el-form-item>
        </template>
        <el-form-item label="">
          <div class="c_form__submit-btn">
            <el-button type="primary" plain @click="closeShareSaveDialog">取消</el-button>
            <el-button v-if="shareSaveForm.id" type="primary" @click="shareSaveSubmitHandle">确认</el-button>
            <el-button v-else type="primary" @click="shareSaveSubmitHandle">确认共享</el-button>
          </div>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.img-arrow {
  transform: rotate(0deg);
  transition: all 1s linear;
  &.is-unfold {
    transform: rotate(90deg);
  }
}
// 设备树
.device-tree {
  .is-active {
    color: var(--el-color-primary);
  }
}
</style>
